Skip to main content

03 通过部分应用和柯里化让函数具象化

在输入、计算和输出这个过程中,输入是最难控制的。

部分应用和柯里化

编写一个函数时,需要传入多个实参,其中一部分实参是先明确的,另一部分是后明确的。

通过部分应用延迟实参传入

函数需要 url、data 和 callback 三个参数的输入,预先知道 url,不知道 data 和 callback。

function orderEventHandler(url, data, callback) {
// ..
}

提前预置已知参数,减少后面需要传入的参数数量,同时增加代码的可读性。

function fetchOrder(data, cb) {
orderEventHandler("http://some.api/order", data, cb);
}

进一步具象化

function getCurrentOrder(cb) {
getCurrentOrder({ order: CURRENT_ORDER_ID }, cb);
}

在函数式编程中,通常会使用部分应用。抽象一个 partial 工具,在先预制部分参数的情况下,后续再传入剩余的参数值。

var fetchOrder = partial(orderEventHandler, "http://some.api/order");
var getCurrentOrder = partial(fetchOrder, { order: CURRENT_ORDER_ID });

partial 工具可以借助闭包或延展操作符(spread operator)来实现。

通过柯里化每次传一个参数

var curriedOrderEvntHandler = curry(orderEventHandler);

var fetchOrder = curriedHttpEvntHandler("http://some.api/order");

var getCurrentOrder = getOrder({ order: CURRENT_ORDER_ID });

getCurrentOrder(function editOrder(order) {
/* .. */
});

其它常用的参数处理工具

在函数式编程中,参数的数量叫做 arity。

改造接口 unary

把一个接收多个参数的函数,变成一个只接收一个参数的函数。

function unary(fn) {
return function oneArg(arg) {
return fn(arg);
};
}

改造参数 constant

把值作为函数参数传入

function constant(v) {
return function value() {
return v;
};
}

promise1.then(action1).then(constant(34)).then(action3);

不做改造 identity

既不改变函数,也不改变参数。输入一个值,返回一个同样的值。

function identity(v) {
return v;
}